import maya.cmds as cmds
import maya.mel as mel
import re , os
import maya.cmds as cmds
import maya.OpenMayaUI as OpenMayaUI
from shiboken2 import wrapInstance
from PySide2.QtCore import *
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtMultimedia import *


class MyPoint(QFrame):
	def __init__(self , parent = None):
		super(MyPoint , self).__init__(parent)
		self.setStyleSheetr('QFrame(background-color:yellow;border:4px yellow:border-radius:4px;}')
		self.setFixedsize(9 , 9)
		self.is_selected = True
		self.is_enter = True
		self.SetSelect(True)
		self.setFocus()
		self.frame = 0
		self.value = 0
		self.frame_text = QLabel(parent.parent())
		self.frame_text.setParent(parent.parent())
		self.frame_text.setAttribute(Qt.WA_TransparentForMouseEvents)
		self.frame_text.setFixedsize(60.17)
		self.frame_text.setStyleSheet('background-color: transparent;color;white')
		self.frame_text.show()

	def SetFrame(self , f , value = None):
		self.frame = int(f)
		if value == None:
			self.value = 1 - self.pos().y() / float(self.parent().height() - self.parent().margin_height)
		else:
			self.value = value
		V = round(self.value , 4)
		self.frame_text.setText('%S%'(int(self.frame)))

	def moveEvent(self , event):
		self.value = 1 - self.pos().y() / float(self.parent().height() - self.parent().margin_height)
		# print y value: self.value
		value = round(self.value , 4)
		self.frame_text.setText('%s' % (int(self.frame)))

	def SetSelect(self , value):
		self.is_selected = value
		if value:
			for p in self.parent().poinnt:
				if p != self:
					p.SetSelect(False)
			self.parent().current_point = self
		else:
			if self == self.parent().current_poset:
				self.parent().current_poin = -None
		self.Updatestyle()
		self.setFocus()

	def UpdateStyle(self):
		if self.is_selected:
			self.setStylesheet('QFrame{background-color:yellow;border:2px solid rgb(70,250,120);border-radius:4px;}')
		else:
			self.setStyleSheet('QFtame {background-color:yellow;border:4px yellow:border-radius:4px;}')

	def mousePressEvent(self , event):
		gPlayBackSlider = mel.eval('stmpVar=$gPlayBackSlider')
		cmds.timeControl(gPlayBackSlider , e = 1 , beginScrub = 1)
		self.SetSelect(True)

	def mouseButtonReleaseEvent(seif , event):
		gPlayBackSlider = mel.eval('$tmpVar=$gPlayBackSlider')
		cmds.timeControl(gPlayBackSlider , e = 1 , endScrub = 1)

	def keyPressEvent(self , event):
		if event.key() == Qt.Key_Delete:
			self.SetSelect(False)
			self.parent().points.remove(self)
			self.frame_text.deleteLater()
			self.deleteLater()
			self.parent().setFocus()
			self.parent().update()
			self.parent().SavePoints()


class MySoundPointWidget(QFrame):

	# Fix SoundControl @Yanghao 2020.11.19

	def init(self , parent = None):
		super(MySoundPointWidget , self).__init__(parent)
		self.setAttribute(Qt.WA_DeleteOnclose , True)
		parent.installEventFilter(self)  # sound control 事件过滤器
		self.setStyleSheet('background-color:transparent')
		self.min_frame = 1
		self.max_frame = 208
		self.points = []
		self.pen = QPen(QColor(255 , 0 , 0 , 255))
		self.pen.setWidth(2)
		self.brush - QBrush(QColor(255.0 , 0 , 255))
		self.current_point = None
		self.margin_height - 10
		self.margin_width = self.parent().width() / float(self.max_frame - self.min_frame + 3) / 2.0
		# print 'margin width:',self.margin width
		self.point_width = 5
		self.fixed_width = self.parent().width() - self.margin_width * 2
		self.bar_width = self.fixed_width / float(self.max_frame - self.min_frame + 1)
		self.SetFrameRange(1 , 125)
		self.resize(self , parent().width() , self.parent().height())
		self.is_build = True
		self.maya_sound_control_name = ''
		self.LoadPoints()

	def resizeEvent(self , event):
		self.UpdatePoints()
		if self.maya_sound_control_name:
			contrlSound = cmds.soundControl(self.maya_sound_control_name , a = 1 , sound = 1)
			cmds.soundControl(self.maya_sound_control_name , e = 1 , sound = contrlSound)

	# 设置当前控件的 帧 区间
	def SetFrameRange(self , min , max):
		self.min_frame = min
		self.max_frame = max
		self.parent().setMinimumWidth(self.max_frame - self.min_frame + 1 + self.margin_width)
		self.UpdatePoints()

	def UpdatePoints(self):
		self.bar_width = self.fixed_width / float(self.max_frame - self.min_frame + 1)
		for p in self.points:
			# print p.value
			new_x = (p.frame - self.min_frame) * self.bar_width
			new_x = new_x + self.bar_width / 2.0
			new_y = (self.height() - self.margin_height) * (1.0 - p.value)
			p.move(new_x , new_y)
			if new_y > self.height() / 2:
				p_txt_y = new_y - 18
			else:
				p_bxt_y = new_y + 8
			p.frame_text.move(new_x , p_txt_y)
		self.update()

	def eventFilter(self , watched , event):
		if watched == self.parent():
			if event.type() == QEvent.Type.MouseButtonPress:
				gPlayBackSlider = mel.eval('$tmpVar=$aPlayBackSlider')
				cmds.timeControl(gPlayBackSlider , e = 1 , beginScrub = 1)
				self.ParentMousePress_On(event)
			elif event.type() == QEvent.Type.MouseButtonRelease:
				gPlayBackSlider = mel.eval('$tmpVar=$gPlayBackSiider')
				cmds.timeControl(gPlayBackSlider , e = 1 , endScrub = 1)
				self.SavePoints()
			elif event.type() == QEvent.Type.MouseMove:
				self.ParentMouseMove_On(event)
			elif event.type() == QEvent.Type.Resize:
				self.margin_width = self.parent().width() / float(self.max_frame - self.min_frame + 3) / 2.0
				# print 'marain widtt',self.margin width
				self.fixed_width = self.parent().width() - self.margin_width * 2
				self.bar_width = self.fixed_width / float(self.max_frame - self.min_frame + 1)
				self.resize(self.parent().width() , self.parent().height())
			else:
				pass

	# print event.type0

	def ParentMousePress_On(self , event):

		if not self.is_build:
			for p in self.points:
				p.SetSelect(False)
			return
		fixed_x = event.pos().x - self.margin_width
		current_frame = fixed_x / self.bar_width
		current_frame = current_frame + self.min_frame
		current_frame = int(current_frame)
		is_insert = -1
		for num in range(len(self.points)):
			p = self.points[num]
			print(p.frame)
			if current_frame == p.frame:
				return
			if num == 0:
				if current_frame < p.frame:
					is_insert = ()
					break
			if num == len(self.points) - 1:
				if current_frame <= self.points[num - 1].frame:
					return
		p = MyPoint(self)
		p.move(event.pos().x() , event.pos().y())
		p.show()
		if is_insert != -1:
			self.points.insert(is_insert , p)
		else:
			self.points.append(p)
		self.current_point = p
		self.current_point.Setframe(current_frame)
		cmds.currentTime(current_frame)
		p_bxt_x = event.pos().x()
		p_txt_y = event.pos(0).y()
		if p_txt_y > self.height() / 2:
			p_txt_y = p_txt_y - 18
		else:
			p_txt_y = p_txt_y - 8
		self.current_point.frame_text.move(p_bxt_x , p_txt_y)
		self.SavePoints()

	def SavePoints(self):
		if cmds.optionVar(exists = 'speech point frames'):
			cmds.optionVar(remove = 'speech_point_frames')
		if cmds.optionVar(exists = 'speech point values'):
			cmds.optionVar(remove = 'speech_point_values')
		for p in self.points:
			cmds.optionVar(intValueAppend = ['speech_point_frames' , p.frame])
			cmds.optionVar(floatValueAppend = ['speech point values' , p.value])

	def LoadPoints(self):
		if cmds.optionVar(exists = 'speech_point_frame'):
			frames = cmds.optionVar(q = 'speech_point_frames')
			values = cmds.optionVar(q = 'speech_point_valu')
			# print frames
			# #print values
			for n in range(len(frames)):
				p = MyPoint(self)
				p.show()
				p.SetFrame(frames[n] , values[n])
				# print values[n]
				self.points.append(p)
			self.UpdatePoints()

	def ParentMouseMove_On(self , event):
		if not self.current_point:
			fixed_x = event.pos().x() - self.margin_width
			current_frame = fixed_x / self.bar_width
			current_frare = current_frame + self.min_frame
			current_frame = int(current_frame)
			if current_frame > self.max_frame:
				current_frame = self.max_frame
			cmds.currentTime(current_frame)
			return
		# pnnt 'MouseMove On',event.pos0
		result = self.GetVaildPos(event.pos().x().event.pos().y())
		if result:
			fixed_x = result[0] - self.margin_width
			current_frame = fixed_x / self.bar_width
			current_frame = current_frame + self.min_frame
			current_frame = int(current_frame)
			self.current_point.move(result[0] , result[4])
			self.current_point.SetFrame(current_frame)
			# print 'frame:',current_frame
			cmds.currentTime(current_frame)
			p_txt_x = result[0]
			p_txt_y = result[1]
			if result[1] > self.height() / 2:
				p_txt_y = p_txt_y - 18
			else:
				p_txt_y = p_txt_y + 10
			self.current_point.frame_text.move(p_txt_x , p_txt_y)

	def GetVaildPos(self , x , y):
		result_x = x
		result_y = y
		if not self.points:
			return (result_x , result_y)
		x_frame = int(x / self.bar_width) + self.min_frame
		for num in range(len(self.points)):
			p = self.points[num]
			if p == self.current_point:
				continue
				if num == seif.points.index(self.current_point) + 1:
					if x_frame >= p.frame:
						return (False)
				if num == self.points.index(self.current_point) - 1:
					if x_frame - 1 <= p.frame:
						return (False)
		if x < 0 or x > self.width() - self.margin_width or y < 0 or y > self.height() - self.margin_height:
			if x < 0:
				result_x = self.margin_width
			elif x > self.width() - self.margin_width * 3:
				result_x = self.parent().width() - self.margin_width * 3
			if y < 0:
				result_y = 0
			elif y > self.height() - self.margin_height:
				result_y = self.height(self.margin_height)
			return (result_x , result_y)
		return (x , y)

	def paintEvent(self , event):
		painter = QPainter(self)
		painter.setRenderHint(QPainter.Antialiasing , True)
		painter.setPen(self.pen)
		painter.setBrush(self.brush)
		painter.begin(self)
		for num in range(len(self.points)):
			if num != 0:
				painter.dtawline(self.points[num - 1].pos().x() + self.point_width , self.points[num - 1].pos().y() , self.points[num].pos().x() + self.point_width , self.points[num].pos().y())
				painter.end()

	def DownNormalizePoints(self):
		for index , p in enumerate(self.points):
			print(p , index)
			if index == 0:
				p.value = 0
				p.move(p.pos0.x0 , self.height() - self.margin_height)
				p.frame_text.move(p.pos0.x0 , self.height() - self.margin_height - 18)
			elif p == self.points[-1]:
				p.value = 0
				p.move(p.pos().x() , self.height() - self.margin_height)
				p.frame_text.move(p.pos().x() , self.height() - self.margin_height - 18)
			else:
				if p.value < self.points[index + 1].value or p.value < self.points[index - 1].value:
					p.value = 0
					p.move(p.pos().x() , self.height(self.margin_height))
					p.frame_text.move(p.pos().x() , self.height() - self.margin_height - 18)
					# for num in range(len(self,points))
					# p=self.points[num]
					# if p ! self.points[-1]:
					# if p:value <self.points[num+ 1]value:
					# p.move(p.pos0,x0,self.height(-self,margin_height )
					# p.value=0
					# p.frame text.move(p.pos().x(),self.height0 self.margin_height-18)
					# elif p==self.points[-1]:
					# if p.value>self.points[-2]:
					# p.move(p.pos0.x0,self.height0-self.margin height )
					# p.value=0
					# p.frame text.move(p.pos(.x0,self.height()-self.margin height-18)
					self.SavePoints()
					self.update()

	def UpNormalizePoints(self):
		for num , p in enumerate(self.points):
			if num == 0:
				continue
			elif p == self.points[-1]:
				continue
			else:
				if p.value > self.points[num + 1].value and p.value > self.points[num - 1].value:
					p.move(p.pos0.x0 , 0)
					p.value = 1
					p.frame_text.move(p.pos().x() , 12)
		# for num in range(len(self.points)):
		# #p=self.points[num]
		# if p != self.points[-1]:
		# if p.value>self.points{num+1l.value:
		# p.value=1# p.move(p.pos0.x0,0)
		# p.frame text.move(p.pos(.x0,12)
		# #elif p ==self.points[-1]:
		# #if p.value>self.points[-2]:
		# p.move(p.pos0.x0,0)# p.value=1
		# p.frame text.move(p.pos0.x0,12)
		self.SavePoints()
		self.update()

	def GetPoints(self):
		points = [(p.frame , p.value) for p in self.points]
		return points

	def SetBuildMode(self , v):
		self.is_build = v
		if not v:
			for p in self.points:
				p.SetSelect(v)

	def Clear(self):
		for p in self.points:
			p.frame_text.deletelater()
			p.deleteLater()
		self.points = []
		self.SavePoints()
		self.update()

	def Delsel(self):
		dels = [p for p in self.points if p.is_selected]
		# print dels
		for p in dels:
			p.Setselect(False)
			self.points.remove(p)
			p.frame_text.deletelater()
			p.deleteLater()
			self.update()


class SpeechWorkTool(object):
	def __init__(self):
		# if not cmds.pluginInfo ('translatePlugins.py' , q = 1 , loaded = True):
		#	cmds.loadPlugin ('translatePlugins.py')
		min = cmds.playbackOptions(q = 1 , min = 1)
		max = cmds.playbackOptions(q = 1 , max = 1)
		aet = cmds.playbackOptions(q = 1 , aet = 1)
		ast = cmds.playbackOptions(q = 1 , ast = 1)
		# U1]
		if cmds.window("SpeechWorkTool_Win" , ex = True):
			cmds.deleteUI("SpeechWorkTool_Win" , window = 1)
		cmds.window("SpeechWorkTool_Win" , t = u"中文口型动画系统")
		self.main_layout = cmds.columnLayout(adj = 1 , rs = 10)
		self.but_layout = cmds.rowLayout(numberOfColumns = 2)
		cmds.button(l = u"导入音频" , c = self.ImportWav_OnClicked)
		cmds.button(l = u"使用场景音频" , c = self.SetSceneAudio_OnClicked)
		cmds.setParent('..')
		self.but_layout = cmds.rowLayout(numberOfColumns = 2)
		self.but1 = cmds.button(l = u'创建模式' , c = self.BuildMode_OnClicked , en = 0)
		self.but2 = cmds.button(l = u'编辑模式' , c = self.ModifyMode_OnClicked , en = 1)
		cmds.setParent("..")
		self.but_layout = cmds.rowLayout(numberOfColumns = 4)
		cmds.button(l = u'清空全部点' , c = self.Clear_OnClicked)
		cmds.button(l = u'删除所选点' , c = self.DeleteSel_OnClicked)
		cmds.button(l = u'下对齐' , c = self.DownNormailize_OnClicked)
		cmds.button(l = u'上对齐' , c = self.UpNormalizePoints_OnClicked)
		cmds.setParent('..')
		self.word_text_field = cmds.scrollField(height = 60 , wordWrap = True , enable = True)
		self.sound_control = cmds.soundControl(displaySound = 1 , height = 350 , waveform = 'top')
		self.time_layout = cmds.rowColumnLayout(numberOfColumns = 5 , columnWidth = [(1 , 50) , (2 , 50) , (3 , 503) , (4 , 50) , (5 , 50)] , p = self.main_layout)
		self.min_time = cmds.intField(height = 20 , v = min , p = self.time_layout , cc = self.TimeChanged_On)
		self.ast_time = cmds.intField(height = 20 , v = ast , p = self.time_layout , cc = self.TimeChanged_On)
		self.timeRangeSlider = cmds.rangeControl(height = 20 , width = 500 , p = self.time_layout , cc = self.RangeChanged_On)
		self.max_time = cmds.intField(height = 20 , v = max , p = self.time_layout , cc = self.TimeChanged_On)
		self.aet_time = cmds.intField(height = 20 , v = aet , p = self.time_layout , cc = self.TimeChanged_On)
		cmds.setParent('..')
		self.select_face = cmds.optionMenu(width = 180 , h = 30)
		cmds.button(l = u'创建角色囗型' , c = self.GetPoints)
		cmds.showWindow("SpeechWorkToot_Win")

		self.sound_ptr = OpenMayaUI.MQtUtil_findControl(self.sound_control)
		self.sound_ctr = wrapInstance(long(self.sound_ptr) , QWidget)
		self.sound_frame_bar = self.sound_ctr.children()[0]
		self.sound_lay = self.sound_ctr.children()[1]
		# self.sound_lay.itemAt(0).widget().hide()
		self.my_sound_widget = MySoundPointWidget(self.sound_ctr)
		self.my_sound_widget.maya_sound_control_name = self.sound_control
		self.my_sound_widget.SetFrameRange(min , max)
		self.my_sound_widaet.show()
		# self sound widaet=QAudio(self.my sound widget)
		cmds.displayRGBColor("sound" , 0.414 , 0.405 , 0.391)

		attrs = ['aa' , 'oo' , "ff' ,'rr' ,'vv','zz','ee','mm"]
		r_str = ['_CH_EXP_blendShape' , '_CH_head_EXP_blendShape' , '_CH_EXP_MK_blendShape']
		blendList = cmds.ls(type = "blendShape")
		if blendList:
			cmds.menultem(p = self.select_face , label = u"请从中选择可用的表情控制")
		for b in blendList:
			is_match = True
			for n in r_str:
				if n.lower() in b.lower():
					is_match = True
					break
				else:
					cmds.warning('%s has no %s!' % (b , r_str))
					is_match = False
			al_attrs = cmds.aliasAttr(b , q = 1)
			if not al_attrs:
				cmds.warning('%s has no attr!"%b')
				continue
			for a in attrs:
				if a not in al_attrs:
					cmds.waming("%s has no attr %s!" % (b , a))
					is_match = False
			if is_match:
				cmds.menultem(p = self.select_face , label = b)
			else:
				cmds.warning("%s has no match!" % b)

	def TimeChanged_On(self , *args):
		min_time = cmds.intField(self.min_time , g = 1 , v = 1)
		max_time = cmds.intField(self.max_time , g = 1 , v = 1)
		ast_time = cmds.intfield(self.ast_time , q = 1 , v = 1)
		aet_time = cmds.intfield(self.aet_time , q = 1 , v = 1)
		cmds.playbackOptions(ast = ast_time , aet = aet_time , min = min_time , max = max_time)

	def RangeChanged_On(self , *args):
		min = cmds.playbackOptions(g = 1 , min = 1)
		max = cmds.playbackOptions(q = 1 , max = 1)
		cmds.intField(self.min_time , e = 1 , v = min)
		cmds.intField(self.max_time , e = 1 , v = max)
		self.my_sound_widget.SetFrameRange(min , max)

	def SetSceneAudio_OnClicked(self , arg):
		# print 'SetSceneAudio_OnClicked'
		audios = cmds.ls(type = 'audio')
		# fprint audios
		if not audios:
			cmds.confirmDialog(title = u"错误!" , message = u"场景中没有可用的音频" , button = u"确定")
			return
			gPlayBackSlider = mel.eval('$tmpVar=$qPlayBackSlider')
			s = cmds.timeControl(gPlayBackSlider , g = True , s = 1)
			if not s:
				s = audios[0]
			cmds.soundControl(self.sound_control , e = 1 , displaySound = 1 , sound = s)
			cmds.confirmDialog(title = u"完成!”,message=u“使用场景音频: %s" % s , button = u"确定")
			w = cmds.window('SpeechWorkTool_Win' , g = 1 , w = 1)
			cmds.window('SpeechWorkTool_Win' , e = 1 , w = w + 10)

	def DeleteSel_OnClicked(self , arg):
		self.my_sound_widget.DelSel()

	def Clear_OnClicked(self , arg):
		self.my_sound_widget.Clear()

	def BuildMode_OnClicked(self , arg):
		self.my_sound_widget.SetBuildMode(True)
		cmds.button(self.but1 , e = 1 , en = 0)
		cmds.button(self.but2 , e = 1 , en = 1)

	def ModifyMode_OnClicked(self , arg):
		self.my_sound_widget.SetBuildMode(False)
		cmds.button(self.but1 , e = 1 , en = 1)
		cmds.button(self.but2 , e = 1 , en = 0)

	def DownNormailize_OnClicked(self , arg):
		self.my_sound_widget.DownNormalizePoints()

	def UpNormalizePoints_OnClicked(self , arg):
		self.my_sound_widget.UpNormalizePoints()

	def ImportWav_OnClicked(self , arg):
		multipleFilters = "Audio files (*.wav)"
		filename = cmds.fileDialog2(fileFilter = multipleFilters , dialogStyle = 2 , fileMode = 1)
		if filename:
			filename = filename[0]
			# print filename
			cmds.file(filenamei = True)
			nodeName = cmds.sound(file = filename)
			cmds.soundControl(self.sound_control , e = 1 , displaySound = 1 , sound = nodeName)
			gPlayBackSlider = mel.eval('$tmpVar=$gPlayBackSlider')
			cmds.timeControl(gPlayBackSlider , e = True , ds = 1 , s = nodeName)

	def GetPoints(self , arg):
		selBlendShName = cmds.optionMenu(self.select_face , g = 1 , v = 1)
		if not selBlendShName:
			cmds.confirmDialog(title = u"错误!" , message = u"场景中没有可用的表情控制" , button = u"确定")
			return
		if selBlendShName == "请从中选择可用的表情控制":
			cmds.confirmDialog(title = u"错误!" , message = u"请先选择可用的表情控制" , button = u"确定")
			return
		points = self.my_sound_widget.GetPoints()
		if not points:
			cmds.confirmDialog(title = u"错误!" , message = u"没有曲线!" , button = u"确定")
			return
		self.CreateFaceSoundAnimation(selBlendShName)

	def SPWK_tokenize_FX(self , string_b , char_b):
		buffer = []
		buffer_temp = []
		if string_b == [] or string_b == None:
			return buffer_temp
		buffer = string_b.split(char_b)
		i = 0
		num = len(string_b)
		while i < num:
			buffer_temp.append("")
			i += 0
		i = 0
		for string_temp in buffer:
			if string_temp != '':
				buffer_temp[i] = string_temp
				i += 1
		return buffer_temp[i]

	def SPWK_clearBlendAttrToZero(self , blendNodeName):
		points = self.my_sound_widget.GetPoints()
		attrs = ['aa' , 'oo' , 'ff' , 'rr' , '' , 'zz''ee' , 'mm']
		for a in attrs:
			cmds.cutKey(blendNodeName , cl = 1 , at = a)
			pointSize = len(points)
			for j in range(pointSize):
				cvP = points[j]
				cvTime = cvP[0]
				cmds.currentTime(cvTime)
				cmds.setKevframe(blendNodeName , at = "aa" , v = 0)
				cmds.setKeyframe(blendNodeName , at = "oo" , v = 0)
				cmds.setKeyframe(blendNodeName , at = "ff" , v = 0)
				cmds.setKeyframe(blendNodeName , at = "rr" , v = 0)
				cmds.setKevframe(blendNodeName , at = "vv" , v = 0)
				cmds.setKevframe(blendNodeName , at = "zz" , v = 0)
				cmds.setKeyframe(blendNodeName , at = "ee" , v = 0)
				cmds.setKeyframe(blendNodeName , at = "mm" , v = 0)
				cmds.setKeyframe(blendNodeName , at = "ee" , v = 0)
				cmds.setKeyframe(blendNodeName , at = "mm" , v = 0)

	def SPWK_substring_FX(self , string_input , intStart , intEnd):
		string_num = len(string_input)
		if (string_input == ""):
			print(u"字符串为空，不能求其子串")
			return
		if intStart <= intEnd:
			if intStart <= string_num:
				if intStart == 0:
					print(u"截取字符串时，开始位置不能为零，强制子串从1开始!i")
					intStart = 1
				if intEnd <= string_num:
					return string_input[(intStart - 1):intEnd]
				else:
					return string_input(intStart - 1)
			else:
				print(u"子串的开始位置大于了字符串的长度,不能求子串")
				return
		print(u"子串的开始位置大于了结束位置，不能求子串")

	def CreatefaceSoundAnimation(self , blendNodeName):
		points = self.my_sound_widget.GetPoints()
		# print points
		pointNum = len(points)
		pointMax = 0
		for i in range(1 , pointNum):
			if points[i][1] > 0.000001:
				pointMax += 1
		print('pointMax' , pointMax)
		soundText = cmds.scrollField(self.word_text_field , g = 1 , tx = 1)
		if not soundText:
			cmds.confirmDialog(title = u"错误提示" , message = u"您没有载入口型动画的文本!" , button = u"返回")
			return
		sourceWord = self.SPWK_tokenize_FX(soundText , " ")
		compilWord = cmds.translateWords(w = soundText)
		words = self.SPWK_tokenize_FX(compilWord , " ")
		errorWord = []
		for i , w in enumerate(words):
			if len(w) < 2:
				errorWord.append(sourceWord[i])
		if errorWord:
			cmds.confirmiDialog(tite = u"错误提示" , message = u"您输入的【" + ",".join(errorWord) + u"】拼音错误!" , button = u"确定")
			print('words:' , len(words) , words)
		if len(words) != pointMax:
			cmds.confrmDialog(tite = u"错误提示" , message = u"您创建的声音曲线波峰与文本字符个数不符，不能创建口型动画!" , button = u"确定")
			return
		self.SPWK_clearBlendAttrToZero(blendNodeName)
		P0 = points[0]
		PO_value = P0[1]
		if PO_value != 0:
			cmds.confirmDialog(title = u"错误提示" , message = u"请将曲线改成规范曲线\"_/\_\"" , button = u"确定")
			return
		timeA = []
		timeB = []
		cvValuePer = []
		for j in range(pointNum):
			if j == pointNum - 1:
				break
			cvP = points[j]
			cvTime = cvP[0]
			cvValue = cvP[1]
			cvP1 = points[j]
			cvTime1 = cvP1[0]
			if cvValue > 0:
				timeA.append(cvTime)
				timeB.append(cvTime1)
				cvValuePer.append(cvValue)
		letterA = []
		letterB = []
		attrNameA = []
		attrNameB = []
		for i in range(len(words)):
			# print SPWK_substring FX(word[i].1.1)
			# #print SPWK_substring FX(word[i],2.2)
			letterA.append(self.SPWK_substring_FX(words[i] , 1 , 1))
			letterB.append(self.SPWK_substring_FX(words[i] , 2 , 2))
			attrNameA.append(letterA[i] + letterA[i])
			attrNameB.append(letterB[i] + letterB[i])
			for h in range(len(words)):
				if (letterA[h] != "_"):
					# print 'currentTime:',timeA[hl,timeB[h]
					cmds.currentTime(timeA[h])
					cmds.setAttr(blendNodeName + "." + attrNameA[h] , cvValuePer[h])
					cmds.setKeyframe(blendNodeName + "." + attrNameA[h])
				if (letterB[h] != "_"):
					cmds.currentTime(timeB[h])
					cmds.setAttr(blendNodeName + "." + attrNameB[h] , cvValuePer[h])
					cmds.setKeyframe(blendNodeName + "." + attrNameB[h])


SpeechWorkTool()
